package service

import (
	"errors"
	"fmt"
	"github.com/vueadmin/app/admin/dto"
	"github.com/vueadmin/app/admin/model"
	"github.com/vueadmin/app/admin/vo"
	"github.com/vueadmin/global"
	"github.com/vueadmin/pkg/cache"
	"github.com/vueadmin/utils/conv"
	"gorm.io/gorm"
	"time"
)

var AdminMembeService = new(adminMembe)

type adminMembe struct{}

/**
 * @description(数据列表)
 * @buildcode(true)
 */
func (p adminMembe) GetPageList(req *dto.AdminMembePageReq) ([]*vo.AdminMembeList, int64, error) {
	var (
		entity model.AdminMembe
		list   []*vo.AdminMembeList
		count  int64
	)
	query := global.DB.Model(&entity)
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq) {
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime) {
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	order := "membe_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	if err := query.Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Order(order).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	query.Count(&count)

	return list, count, nil
}

/**
 * @description(修改排序开关)
 * @buildcode(true)
 */
func (p adminMembe) UpdateExt(req map[string]interface{}) error {
	entity := model.AdminMembe{}
	if err := global.DB.Model(&entity).Where("membe_id", req["membe_id"]).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(添加)
 * @buildcode(true)
 */
func (p adminMembe) Add(req *dto.AdminMembeAddReq) (uint, error) {
	entity := model.AdminMembe{}
	entity.Username = req.Username
	entity.Sex = req.Sex
	entity.Mobile = req.Mobile
	entity.Pic = req.Pic
	entity.Email = req.Email
	entity.Password = conv.EncryptPassword(req.Password)
	entity.Amount = req.Amount
	entity.Status = req.Status
	entity.Ssq = req.Ssq
	entity.CreateTime = conv.NowUnix()

	if err := global.DB.Create(&entity).Error; err != nil {
		return 0, err
	}
	return entity.MembeId, nil
}

/**
 * @description(修改)
 * @buildcode(true)
 */
func (p adminMembe) Update(req *dto.AdminMembeUpdateReq) error {
	entity := model.AdminMembe{
		MembeId: req.MembeId,
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	entity.Username = req.Username
	entity.Sex = req.Sex
	entity.Mobile = req.Mobile
	entity.Pic = req.Pic
	entity.Email = req.Email
	entity.Amount = req.Amount
	entity.Status = req.Status
	entity.Ssq = req.Ssq
	entity.CreateTime = conv.UnixTime(req.CreateTime)

	field := conv.StringToSlice("username,sex,mobile,pic,email,amount,status,ssq,create_time", ",")

	if err := global.DB.Select(field).Updates(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取修改详情)
 * @buildcode(true)
 */
func (p adminMembe) GetUpdateInfo(req *dto.AdminMembeGetUpdateInfoReq) (*model.AdminMembe, error) {
	entity := model.AdminMembe{}
	if err := global.DB.Where("membe_id = ?", req.MembeId).Limit(1).First(&entity).Error; err != nil {
		return nil, err
	}
	return &entity, nil
}

/**
 * @description(删除)
 * @buildcode(true)
 */
func (p adminMembe) Delete(req *dto.AdminMembeDeleteReq) error {
	query := global.DB.Where("membe_id IN ?", conv.Slice(req.MembeId))
	if err := query.Delete(&model.AdminMembe{}).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(查看详情)
 * @buildcode(true)
 */
func (p adminMembe) Detail(req *dto.AdminMembeDetailReq) (*vo.AdminMembeDetail, error) {
	var info vo.AdminMembeDetail
	query := global.DB.Model(&model.AdminMembe{})
	if err := query.Where("membe_id = ?", req.MembeId).Limit(1).First(&info).Error; err != nil {
		return nil, err
	}
	return &info, nil
}

/**
 * @description(重置密码)
 * @buildcode(true)
 */
func (adminMembe) ResetPwd(req *dto.AdminMembeResetPwdReq) error {
	entity := model.AdminMembe{
		MembeId: conv.Uint(req.MembeId),
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	if err := global.DB.Model(&entity).Update("password", conv.EncryptPassword(req.Password)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(导入)
 * @buildcode(true)
 */
func (p adminMembe) Import(req []dto.AdminMembeImportReq) error {
	var entity []*model.AdminMembe
	for _, v := range req {
		entity = append(entity, &model.AdminMembe{
			Username:   conv.String(v.Username),
			Sex:        conv.Int(conv.GetValByKey(v.Sex, `[{"key":"男","label_color":"primary","val":1},{"key":"女","label_color":"warning","val":2}]`)),
			Mobile:     conv.String(v.Mobile),
			Pic:        conv.String(v.Pic),
			Email:      conv.String(v.Email),
			Password:   conv.EncryptPassword(v.Password),
			Amount:     conv.Float64(v.Amount),
			Status:     conv.Int8(conv.GetValByKey(v.Status, `[{"key":"正常","label_color":"primary","val":1},{"key":"禁用","label_color":"danger","val":0}]`)),
			Ssq:        conv.StringToSlice(v.Ssq, "-"),
			CreateTime: conv.NowUnix(),
		})
	}

	if err := global.DB.Create(&entity).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(客户端导出)
 * @buildcode(true)
 */
func (p adminMembe) Export(req *dto.AdminMembePageReq) ([]*vo.AdminMembeExport, int64, error) {
	var (
		entity model.AdminMembe
		list   []*vo.AdminMembeExport
		count  int64
	)
	query := global.DB
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq) {
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime) {
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	order := "membe_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	if err := query.Model(&entity).Order(order).Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	for k, v := range list {
		list[k].Sex = conv.GetItemVal(v.Sex, `[{"key":"男","label_color":"primary","val":1},{"key":"女","label_color":"warning","val":2}]`)
		list[k].Status = conv.GetItemVal(v.Status, `[{"key":"正常","label_color":"primary","val":1},{"key":"禁用","label_color":"danger","val":0}]`)
		list[k].CreateTime = conv.DateTime(conv.Int64(v.CreateTime))
	}
	if req.Page == 1 {
		cache.Gocache.Delete("membe_count")
	}
	cache_count := conv.Int64(cache.Gocache.Getx("membe_count"))
	if cache_count == 0 {
		query.Model(&entity).Count(&count)
		cache.Gocache.Setx("membe_count", count, 300*time.Second)
	} else {
		count = cache_count
	}
	return list, count, nil
}

/**
 * @description(服务端导出)
 * @buildcode(true)
 */
func (p adminMembe) ExportServer(req *dto.AdminMembePageReq) ([]*vo.AdminMembeExportServer, int64, error) {
	var (
		entity model.AdminMembe
		list   []*vo.AdminMembeExportServer
		count  int64
	)
	query := global.DB
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq) {
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime) {
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	order := "membe_id desc"
	if !conv.IsEmpty(req.Sort) && !conv.IsEmpty(req.Order) {
		order = fmt.Sprintf("%s %s", req.Sort, req.Order)
	}
	if err := query.Model(&entity).Order(order).Limit(req.Limit).Offset((req.Page - 1) * req.Limit).Find(&list).Error; err != nil {
		return nil, 0, err
	}
	for k, v := range list {
		list[k].Sex = conv.GetItemVal(v.Sex, `[{"key":"男","label_color":"primary","val":1},{"key":"女","label_color":"warning","val":2}]`)
		list[k].Status = conv.GetItemVal(v.Status, `[{"key":"正常","label_color":"primary","val":1},{"key":"禁用","label_color":"danger","val":0}]`)
		list[k].CreateTime = conv.DateTime(conv.Int64(v.CreateTime))
	}
	if req.Page == 1 {
		cache.Gocache.Delete("membe")
		cache.Gocache.Delete("membe_count")
	}
	cache_count := conv.Int64(cache.Gocache.Getx("membe_count"))
	if cache_count == 0 {
		query.Model(&entity).Count(&count)
		cache.Gocache.Setx("membe_count", count, 300*time.Second)
	} else {
		count = cache_count
	}
	data := cache.Gocache.Getx("membe")
	if data == nil {
		data = []*vo.AdminMembeExportServer{}
	}
	for _, v := range list {
		data = append(data.([]*vo.AdminMembeExportServer), v)
	}
	cache.Gocache.Setx("membe", data, 300*time.Second)

	return data.([]*vo.AdminMembeExportServer), count, nil
}

/**
 * @description(充值)
 * @buildcode(true)
 */
func (p adminMembe) Jia(req *dto.AdminMembeJiaReq) error {
	entity := model.AdminMembe{
		MembeId: conv.Uint(req.MembeId),
	}
	if err := global.DB.Model(&entity).Update("amount", gorm.Expr("amount + ?", req.Amount)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(扣除)
 * @buildcode(true)
 */
func (p adminMembe) Jian(req *dto.AdminMembeJianReq) error {
	entity := model.AdminMembe{
		MembeId: conv.Uint(req.MembeId),
	}
	if err := global.DB.Limit(1).First(&entity).Error; err != nil {
		return err
	}
	if req.Amount > entity.Amount {
		return errors.New("数据不足!")
	}
	if err := global.DB.Model(&entity).Update("amount", gorm.Expr("amount - ?", req.Amount)).Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(状态禁用)
 * @buildcode(true)
 */
func (p adminMembe) Forbidden(req *dto.AdminMembeForbiddenReq) error {
	entity := model.AdminMembe{}
	if err := global.DB.Model(&entity).Where("membe_id IN ?", conv.Slice(req.MembeId)).Update("status", "0").Error; err != nil {
		return err
	}
	return nil
}

/**
 * @description(获取积分汇总)
 * @buildcode(true)
 */
func (p adminMembe) GetAmountSum(req *dto.AdminMembePageReq) float64 {
	var (
		entity model.AdminMembe
		sum    float64
	)
	query := global.DB.Model(&entity)
	if !conv.IsEmpty(req.MembeId) {
		query = query.Where("membe_id = ?", req.MembeId)
	}
	if !conv.IsEmpty(req.Username) {
		query = query.Where("username = ?", req.Username)
	}
	if !conv.IsEmpty(req.Sex) {
		query = query.Where("sex = ?", req.Sex)
	}
	if !conv.IsEmpty(req.Mobile) {
		query = query.Where("mobile = ?", req.Mobile)
	}
	if !conv.IsEmpty(req.Email) {
		query = query.Where("email = ?", req.Email)
	}
	if !conv.IsEmpty(req.Status) {
		query = query.Where("status = ?", req.Status)
	}
	if !conv.IsEmpty(req.Ssq) {
		query = query.Where("ssq like ?", "%"+conv.Join(req.Ssq, "-")+"%")
	}
	if !conv.IsEmpty(req.CreateTime) {
		query = query.Where("create_time BETWEEN ? AND ?", conv.UnixTime(req.CreateTime[0]), conv.UnixTime(req.CreateTime[1]))
	}
	query.Select("sum(amount)").Scan(&sum)
	return sum
}
